package com.adms.redis;

import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.StringRedisSerializer;

public class RedisCache implements Cache {
	private static RedisTemplate<Object,Object> redisTemplate;
	private final String id;
	private final String prefix;

	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

	public RedisCache(final String id) {
		if (id == null) {
			throw new IllegalArgumentException("Cache instances require an ID");
		}
		this.id = id;
		this.prefix = "mybatis:"+id+":";
	}

	@Override
	public void clear() {
		Set<Object> keys = redisTemplate.keys(prefix+"*");
		redisTemplate.delete(keys);
	}

	@Override
	public String getId() {
		return this.id;
	}

	@Override
	public Object getObject(Object key) {

		key = prefix+key;
		ValueOperations<Object, Object> opsForValue = redisTemplate.opsForValue();
		Object result = opsForValue.get(key);
		return result;
	}

	@Override
	public ReadWriteLock getReadWriteLock() {
		return this.readWriteLock;
	}

	@Override
	public int getSize() {
		Set<Object> keys = redisTemplate.keys(prefix+"*");
		return keys.size();
	}

	@Override
	public void putObject(Object key, Object value) {
		key = prefix + key;
		ValueOperations<Object, Object> opsForValue = redisTemplate.opsForValue();
		opsForValue.set(key, value);
	}

	@Override
	public Object removeObject(Object key) {
		key = prefix + key;
		Boolean result = redisTemplate.delete(key);
		return result;
	}

	public static void setRedisTemplate(RedisTemplate<Object,Object> redisTemplate) {
		redisTemplate.setKeySerializer(new StringRedisSerializer());
		RedisCache.redisTemplate = redisTemplate;
	}

}